package team.seekers.hula.course.course.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import team.seekers.hula.common.entity.PageResult;
import team.seekers.hula.common.entity.enums.CourseRoleEnum;
import team.seekers.hula.course.course.dao.CourseDao;
import team.seekers.hula.course.course.entity.dao.CourseDO;
import team.seekers.hula.course.course.entity.dto.CourseCreateDTO;
import team.seekers.hula.course.course.entity.dto.CourseListReqDTO;
import team.seekers.hula.course.course.entity.dto.CourseUpdateDTO;
import team.seekers.hula.course.course.entity.dto.CourseUpdateLogDTO;
import team.seekers.hula.course.course.entity.vo.CourseManageInfoVO;
import team.seekers.hula.course.course.entity.vo.CourseManageListVO;
import team.seekers.hula.course.courseUser.dao.CourseUserDao;
import team.seekers.hula.course.courseUser.entity.dao.CourseUserDO;
import team.seekers.hula.course.courseUser.service.CourseUserService;
import team.seekers.hula.course.resource.sectionContent.dao.SectionContentDao;
import team.seekers.hula.course.resource.sectionContent.entity.dao.SectionContentDO;
import team.seekers.hula.course.resource.sectionContent.entity.dto.RollBackSectionContentDTO;
import team.seekers.hula.course.structure.chapter.dao.ChapterDao;
import team.seekers.hula.course.structure.chapter.entity.dao.ChapterDO;
import team.seekers.hula.course.structure.chapter.service.ChapterService;
import team.seekers.hula.course.structure.section.dao.SectionDao;
import team.seekers.hula.course.structure.section.entity.dao.SectionDO;
import team.seekers.hula.course.structure.section.service.SectionService;
import team.seekers.hula.user.user.entity.dao.UserDO;
import team.seekers.hula.user.user.service.UserService;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Service
public class CourseManageService {

    @Resource
    private CourseDao courseDao;

    @Resource
    private CourseUserService courseUserService;

    @Resource
    private SectionContentDao sectionContentDao;

    @Resource
    private SectionDao sectionDao;

    @Resource
    private ChapterDao chapterDao;

    @Resource
    private SectionService sectionService;

    @Resource
    private ChapterService chapterService;

    @Resource
    private CourseUserDao courseUserDao;

    @Resource
    private UserService userService;

    public String createCourse(CourseCreateDTO reqDTO) {
        CourseDO courseDO = new CourseDO();
        BeanUtils.copyProperties(reqDTO,courseDO);
        courseDao.save(courseDO);
        // 将创建人绑定课程关系
        CourseUserDO courseUserDO = CourseUserDO.builder()
                .courseId(courseDO.getId())
                .role(CourseRoleEnum.MANAGER.getType())
                .isFixed(1)
                .userId(reqDTO.getUserId()).build();
        courseUserDao.save(courseUserDO);
        return courseDO.getId();
    }

    @Transactional(rollbackFor = Exception.class)
    public void delete(CourseUpdateDTO manageDTO) {
        // TODO 删除所有关联的章节课时
        courseDao.removeById(manageDTO.getId());
    }

    @Transactional(rollbackFor = Exception.class)
    public void updateCourse(CourseUpdateDTO manageDTO) {
        CourseDO courseDO = new CourseDO();
        BeanUtils.copyProperties(manageDTO,courseDO);
        courseDao.updateById(courseDO);
    }

    /**
     * 获得课程详情，包括课程目录
     */
    public CourseManageInfoVO queryById(String courseId) {
        CourseDO courseDO = courseDao.getById(courseId);
        CourseManageInfoVO courseManageInfoVO = new CourseManageInfoVO();
        BeanUtils.copyProperties(courseDO, courseManageInfoVO);

        // 查询用户情况
        courseManageInfoVO.setUserCount(courseUserService.countBuy(courseManageInfoVO.getId()));
        courseManageInfoVO.setFixedCount(courseUserService.countFixed(courseManageInfoVO.getId()));

        // 查询课时情况
        courseManageInfoVO.setSectionCount(sectionService.countByCourseId(courseManageInfoVO.getId()));
        courseManageInfoVO.setChapterCount(chapterService.countByCourseId(courseManageInfoVO.getId()));


        return courseManageInfoVO;
    }

    public PageResult<CourseUpdateDTO> page(CourseListReqDTO req) {
        LambdaQueryChainWrapper<CourseDO> query = courseDao.lambdaQuery().select(
                CourseDO::getId,
                CourseDO::getName,
                CourseDO::getUserId,
                CourseDO::getCover,
                CourseDO::getDescription,
                CourseDO::getStatus,
                CourseDO::getGmtCreate
        );
        if (StringUtils.isNotBlank(req.getName())) {
            query.and(o1 ->
                    o1.like(CourseDO::getName, req.getName()).or()
                      .like(CourseDO::getDescription, req.getName()));
        }
        Page<CourseDO> page = query.page(new Page<>(req.getPageNow(), req.getPageSize()));


        ArrayList<CourseUpdateDTO> courseUpdateDTOS = new ArrayList<>();
        for (CourseDO record : page.getRecords()) {
            CourseUpdateDTO courseUpdateDTO = new CourseUpdateDTO();
            BeanUtils.copyProperties(record, courseUpdateDTO);
            UserDO userDO = userService.getOne(new QueryWrapper<UserDO>().eq("id", record.getUserId()));
            if (null != userDO) {
                if (StringUtils.isNotBlank(userDO.getNickname())) {
                    courseUpdateDTO.setNickname(userDO.getNickname());
                }
            }
            courseUpdateDTOS.add(courseUpdateDTO);
        }


        return new PageResult<>(page.getPages(), courseUpdateDTOS);
    }

    public PageResult<CourseManageListVO> list(CourseListReqDTO reqDTO) {
        LambdaQueryChainWrapper<CourseDO> query = courseDao.lambdaQuery().select(
                CourseDO::getId,
                CourseDO::getName
        ).like(CourseDO::getName, reqDTO.getName());

        Page<CourseDO> page = query.page(new Page<>(1, 10));

        ArrayList<CourseManageListVO> courseManageListVOS = new ArrayList<>();
        for (CourseDO record : page.getRecords()) {
            CourseManageListVO manageListDTO = CourseManageListVO.builder()
                    .id(record.getId())
                    .name(record.getName()).build();
            courseManageListVOS.add(manageListDTO);
        }
        return new PageResult<>(page.getPages(), courseManageListVOS);
    }

    public List<CourseManageListVO> listMyAdmin(String userId) {
        List<String> courseIdList = courseUserService.listUserBindCourseIdList(userId, 1);
        if(courseIdList.size() == 0){
            return new ArrayList<>();
        }
        List<CourseDO> courseDOS = courseDao.lambdaQuery().in(CourseDO::getId, courseIdList).list();
        return CourseDO.toMangeListVOList(courseDOS);
    }

    /**
     * 1.0 暂时不做
     * @param logDTO
     */
    public void rollBackDelete(CourseUpdateLogDTO logDTO) {
        // 确定回滚的范围
        boolean chapterDelete = StringUtils.isEmpty(logDTO.getDeleteChapterId());
        boolean sectionDelete = logDTO.getDeleteSectionIds().size() == 0;
        boolean sectionContentDelete = logDTO.getDeleteSectionContentIds().size() == 0;
        // 回滚节内容
        if(sectionContentDelete){
            // 回滚is_delete字段
            for (String deleteSectionId : logDTO.getDeleteSectionContentIds()) {
                UpdateWrapper<SectionContentDO> deleteWrapper = new UpdateWrapper<>();
                deleteWrapper.eq("id",deleteSectionId).set("is_delete",0);
                sectionContentDao.update(deleteWrapper);
            }
            // 维护sequence
            for (String lowSequenceSectionContentId : logDTO.getLowSequenceSectionContentIds()) {
                UpdateWrapper<SectionContentDO> sequenceWrapper = new UpdateWrapper<>();
                sequenceWrapper.eq("id",lowSequenceSectionContentId).setSql("`sequence`=`sequence`+1");
                sectionContentDao.update(sequenceWrapper);
            }
        }
        // 回滚节
        if(sectionDelete) {
            // 回滚is_delete字段
            for (String deleteSectionId : logDTO.getDeleteSectionIds()) {
                UpdateWrapper<SectionDO> deleteWrapper = new UpdateWrapper<>();
                deleteWrapper.eq("id",deleteSectionId).set("is_delete",0);
                sectionDao.update(deleteWrapper);
            }
            // 维护sequence
            for (String lowSequenceSectionId : logDTO.getLowSequenceSectionIds()) {
                UpdateWrapper<SectionDO> sequenceWrapper = new UpdateWrapper<>();
                sequenceWrapper.eq("id",lowSequenceSectionId).setSql("`sequence`=`sequence`+1");
                sectionDao.update(sequenceWrapper);
            }
        }
        // 回滚章
        if(chapterDelete) {
            // 回滚is_delete字段
            UpdateWrapper<ChapterDO> deleteWrapper = new UpdateWrapper<>();
            deleteWrapper.eq("id",logDTO.getDeleteChapterId()).set("is_delete",0);
            chapterDao.update(deleteWrapper);

            // 维护sequence
            for (String lowChapterId : logDTO.getLowSequenceChapterIds()) {
                UpdateWrapper<ChapterDO> sequenceWrapper = new UpdateWrapper<>();
                sequenceWrapper.eq("id",lowChapterId).setSql("`sequence`=`sequence`+1");
                chapterDao.update(sequenceWrapper);
            }
        }
    }


    public void rollBackSectionContent(RollBackSectionContentDTO sectionContentDTO) {
        SectionContentDO sectionContentOld = sectionContentDao.getById(sectionContentDTO.getSectionContentId());
        // 没做过修改，不能回滚
        if (sectionContentOld.getVersion() == 0){
            return;
        }
        // 把当前版本设置为不可见
        SectionContentDO sectionContentDO = new SectionContentDO();
        sectionContentDO.setId(sectionContentOld.getId());
        sectionContentDO.setIsVisible(0);
        sectionContentDO.setVersionDescription(sectionContentDTO.getVersionDescription());
        sectionContentDao.updateById(sectionContentDO);
        // 找到上一个版本
        QueryWrapper<SectionContentDO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("sequence",sectionContentOld.getSequence());
        if(StringUtils.isNotBlank(sectionContentDTO.getSectionId())){
            queryWrapper.eq("section_id",sectionContentDTO.getSectionId());
            }else if(StringUtils.isNotBlank(sectionContentDTO.getChapterId())){
            queryWrapper.eq("chapter_id",sectionContentDTO.getChapterId());
            // 和章绑定的sectionContent序列号为0
            queryWrapper.eq("sequence",0);
        }
        queryWrapper.eq("version",sectionContentOld.getVersion()-1);
        SectionContentDO sectionContentNew = sectionContentDao.getOne(queryWrapper);
        // 将上一个版本变更为可见
        UpdateWrapper<SectionContentDO> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id",sectionContentNew.getId())
                .set("is_visible",1);
        sectionContentDao.update(updateWrapper);
    }
}
